******************************************************************************************
** 	Replications file for American Political Science Review 							**
**  I'm a Survivor: Political Dynamics in Bureaucratic Elites' Partisan Identification 	**
** 	Geys, Lægreid, Murdoch and Yackee													**
******************************************************************************************

** NOTE: Data from the American State Administrators Project (ASAP) is a central part of the article's dataset, and cannot be shared without a signed data transfer agreement. We are happy to provide a replication dataset that reproduces all results from the manuscript after the signed transfer agreement (on the ASAP website; https://asap.wisc.edu/dataset).   

clear all

**** Read in data
global paper = "E:"  // Insert location of the folder with the replication dataset here

use "$paper\APSR replication files\APSR replication data_anon.dta", replace

**********************************************
*****  INITIAL CALCULATIONS AND CHECKS  ******
**********************************************

***** Calculate share of ASAP respondents not answering party identification question
** (mentioned in main text)
fre PartyID

***** Calculate share of ASAP respondents who witnessed at least one change in governor during their tenure
** (mentioned in main text)
preserve

drop if Length_State ==. | state==.
sort PanelID time
by PanelID: gen wave = _n
replace wave = 1 if PanelID==.
by PanelID: egen wavemax = max(wave)
keep if wavemax==wave

gen survivor = 1 if Length_State > ((year - LastGovChange) + 1)

* All observations
egen num_survivor = count(survivor)
egen num_obs = max(_n)
gen pr_survivor = num_survivor / num_obs
summ num_survivor pr_survivor num_obs

* By appointment status
gen Appointed=.
replace Appointed=1 if Position<=3
replace Appointed=0 if Position>=4 & Position~=.
sort Appointed
by Appointed: egen num_survivor2 = count(survivor)
by Appointed: egen num_obs2 = max(_n)
gen pr_survivor2 = num_survivor2 / num_obs2
by Appointed: summ num_survivor2 pr_survivor2 num_obs2

restore


***** Consistency of party ID and liberal/conservative placement
** (mentioned in main text)
pwcorr LibCons PartyID_det, sig obs
scatter LibCons PartyID_det, jitter(10) jitterseed(2024) xlab(0(1)6) mcolor(gs4) note("Pairwise correlation: r=-0.587, p=0.000, N=3,768")


**************************************
***       Table 1, column 1        ***
**************************************
tab Position


*********************************************************************
*** Table A.1 Descriptives and balancing checks on matched sample ***
*********************************************************************
gen Match = 1 if PanelID~=.
replace Match = 0 if PanelID==.
sort PanelID year
by PanelID: gen wave = _n
replace PanelID = 1000 + wave if PanelID==.
replace wave = 1 if PanelID>1000


***** REMOVED FOR ANONIMITY REASONS


**************************************
**************************************
*****  START OF MAIN ANALYSIS   ******
**************************************
**************************************

***** Keep only panel respondents
replace PanelID=. if PanelID > 1000

keep if PanelID~=.
xtset PanelID time

***** Share of *panel* respondents not answering party identification question
** (mentioned in main text)
fre PartyID

***** Calculate share of *panel* respondents answering 2, 3 or more survey waves
** (mentioned in main text)
preserve
duplicates tag PanelID, gen(DUP1)
duplicates drop PanelID, force
fre DUP1
restore


**************************************
***       Table 1, column 2        ***
**************************************
tab Position


*****************************************
*** Create main party shift variables ***
*****************************************

***** Generate variable for change in (direction-specific) partisan identification
** Negative if towards Democrat and positive if towards Republican
gen ShiftPartyID=. 		// Independent as unified group (whole period)
gen ShiftPartyID2 = . 	// Independent asked for 'leaning' (since 1974)
replace ShiftPartyID= PartyID - l.PartyID
replace ShiftPartyID2= PartyID_det - l.PartyID_det

***** Generate dummy for change to missing
gen HidePartyID=. // Answering in wave 1, but not wave 2
replace HidePartyID=1 if PartyID==. & l.PartyID~=.
replace HidePartyID=0 if HidePartyID~=1 & l.PartyID~=.

gen HidPartyID=.  // Answering in wave 2, but not wave 1
replace HidPartyID=1 if l.PartyID==. & PartyID~=.
replace HidPartyID=0 if HidPartyID~=1 & PartyID~=.
replace HidPartyID=. if wave==1

***** Generate variable for change in partisanship of Governor accounting for direction
** Negative if towards Democrat and positive if towards Republican
gen ShiftGovParty=. 
replace ShiftGovParty= GovernorParty - l.GovernorParty

***** Generate variable for change in partisanship of President accounting for direction
** Negative if towards Democrat and positive if towards Republican
gen ShiftPresParty=. 
replace ShiftPresParty= PresidentParty - l.PresidentParty

***** Generate variable for change in partisan support for party in state
** Negative if towards Democrat and positive if towards Republican
gen ShiftVoters=. 
replace ShiftVoters= ((l.DemSharePres*100)-(l.RepSharePres*100)) - ((DemSharePres*100)-(RepSharePres*100))

***** Generate dummy for change in partisanship of State House, Senate or Legislature
** Negative if towards Democrat and positive if towards Republican
gen ShiftHouseParty=. 
replace ShiftHouseParty= StateHouseParty - l.StateHouseParty
gen ShiftSenParty=. 
replace ShiftSenParty= StateSenParty - l.StateSenParty
gen ShiftLegParty=. 
replace ShiftLegParty= StateLegParty - l.StateLegParty


**********************************************************************
*** Figure A.1: Distribution of respondent party change variables  ***
**********************************************************************
hist ShiftPartyID, width(1) start(-2.5) percent xlabel(-2(1)2) xtitle("Shift party ID") color(gs6)
graph save Graph "$paper\FigA1a.gph", replace
hist ShiftPartyID2, width(1) start(-4.5) percent xlabel(-4(1)4) xtitle("Shift party ID (detailed)") color(gs6)
graph save Graph "$paper\FigA1b.gph", replace
graph combine FigA1a.gph FigA1b.gph, ycommon
graph save Graph "$paper\FigA1.gph", replace
erase "$paper\FigA1a.gph"
erase "$paper\FigA1b.gph"

***** Distribution of partisan identification shifts
** (mentioned in main text)
tab ShiftPartyID
tab ShiftPartyID2


***** Explore ASAP respondents who witnessed multiple changes in governor / president during their career
** (mentioned in main text)
preserve
by PanelID: egen temp = max(wave)
keep if temp>=3
drop temp
unique PanelID
keep year time wave PanelID state ShiftPartyID ShiftPartyID2 ShiftGovParty ShiftPresParty
restore


***** Calculate number of people moving
gen Align = 1 if PartyID == GovernorParty & PartyID~=2 & GovernorParty~=2
replace Align = 0 if PartyID != GovernorParty | PartyID==2 | GovernorParty==2
replace Align = . if PartyID==. | GovernorParty==.
fre Align if l.Align==0 & ShiftPartyID==0 & ShiftGovParty~=0
fre ShiftPartyID2 if ShiftGovParty~=0

replace LastinYears = . if ShiftGovParty ==.


********************************************************************
***   Table A.2 Descriptives and balancing checks on treatment   ***
********************************************************************

***** REMOVED FOR ANONIMITY REASONS



*********************************************************************
** Figure A.2: Persistence or rather reversals in Governor shifts? **
*********************************************************************
preserve 

drop if wave>=3
replace ShiftGovParty=f.ShiftGovParty if f.ShiftGovParty~=.

replace LAGShiftGovParty = f.LAGShiftGovParty if f.LAGShiftGovParty ~=.
tab ShiftGovParty LAGShiftGovParty if wave==1, chi2 row  // significant at 1% 
tabplot ShiftGovParty LAGShiftGovParty if wave==1, showval subtitle("") ytitle("Shift Governor party") xtitle("Shift Governor party (LAG)") color(gs7) note("{bf:Note:} Chi{superscript:2}(16) = 606.18; p = 0.000")
graph save Graph "$paper\FigA2.gph", replace

restore


***************************************************************
***   Table A.3 Pre-trends of partisan turnover treatment   ***
***************************************************************
ologit ShiftPartyID ShiftGovParty f.ShiftGovParty i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID2 ShiftGovParty f.ShiftGovParty i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)


********************************
***  Table 2: Main results   ***
********************************

** Panel I
ologit ShiftPartyID ShiftGovParty i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID) 
ologit ShiftPartyID ShiftGovParty i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1) & (ShiftPartyID~=-2 & ShiftPartyID~=2), cluster(PanelID)
ologit ShiftPartyID ShiftGovParty i.time if l.PartyID~=2 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID ShiftLegParty i.time, cluster(PanelID) 

** Panel II
ologit ShiftPartyID2 ShiftGovParty i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID) 
ologit ShiftPartyID2 ShiftGovParty i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1) & (ShiftPartyID~=-2 & ShiftPartyID~=2), cluster(PanelID)
ologit ShiftPartyID2 ShiftGovParty i.time if l.PartyID~=2 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID2 ShiftLegParty i.time, cluster(PanelID)


***********************************************************************
***  Figure 1: Display predicted probabilities (using mlogit model) ***
***********************************************************************
mlogit ShiftPartyID ShiftGovParty i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1) & (ShiftPartyID~=-2 & ShiftPartyID~=2), cluster(PanelID)
margins, at(ShiftGovParty=(-2(2)2)) predict(outcome(1)) predict(outcome(-1)) 
marginsplot, xtitle("Shift Governor party") ytitle("Predicted probability") title("") plot1opts(mcolor(black) lcolor(black)) ci1opts(mcolor(black) lcolor(black)) plot2opts(msymbol(S) mcolor(grey%50) lcolor(grey%50) lpattern(-)) ci2opts(mcolor(grey%50) lcolor(grey%50) lpattern(-)) legend(order(1 "Left Change in Party ID" 2 "Right Change in Party ID") position(6) rows(1))
margins, at(ShiftGovParty=(-2(2)2)) predict(outcome(1)) predict(outcome(-1)) coefl post
lincom _b[1._predict#2._at] - _b[1._predict#1._at] // Diff. in prob of right move under Gov *no move vs. left move*
lincom _b[1._predict#2._at] - _b[1._predict#3._at] // Diff. in prob of right move under Gov *no move vs. right move*
lincom _b[2._predict#2._at] - _b[2._predict#1._at] // Diff. in prob of left move under Gov *no move vs. left move*
lincom _b[2._predict#2._at] - _b[2._predict#3._at] // Diff. in prob of left move under Gov *no move vs. right move*
lincom _b[1._predict#1._at] - _b[1._predict#3._at] // Diff. in prob of right move under Gov *right vs. left move*
lincom _b[2._predict#1._at] - _b[2._predict#3._at] // Diff. in prob of left move under Gov *right vs. left move*


**************************************************************************************************
*** Table A.4: Including each respondent only ONCE (i.e. first wave to second wave difference) ***
**************************************************************************************************
ologit ShiftPartyID ShiftGovParty i.time if wave==2 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID2 ShiftGovParty i.time if wave==2 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID ShiftLegParty i.time if wave==2 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID2 ShiftLegParty i.time if wave==2 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)


********************************************************************************
*** Table A.5: Robustness checks using only respondents from '4-year' waves) ***
********************************************************************************
gen FourWave = 0
replace FourWave = 1 if Match_6468 ==1 | Match_7478==1 | Match_8488==1 | Match_9498==1 | Match_0408==1

** Panel I
ologit ShiftPartyID ShiftGovParty i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1) & FourWave==1, cluster(PanelID) 
ologit ShiftPartyID ShiftGovParty i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1) & (ShiftPartyID~=-2 & ShiftPartyID~=2) & FourWave==1, cluster(PanelID)
ologit ShiftPartyID ShiftGovParty i.time if l.PartyID~=2 & (ShiftGovParty~=-1 & ShiftGovParty~=1) & FourWave==1, cluster(PanelID)
ologit ShiftPartyID ShiftLegParty i.time if FourWave==1, cluster(PanelID)  // Significant at 10%

** Panel II
ologit ShiftPartyID2 ShiftGovParty i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1) & FourWave==1, cluster(PanelID) 
ologit ShiftPartyID2 ShiftGovParty i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1) & (ShiftPartyID~=-2 & ShiftPartyID~=2) & FourWave==1, cluster(PanelID)
ologit ShiftPartyID2 ShiftGovParty i.time if l.PartyID~=2 & (ShiftGovParty~=-1 & ShiftGovParty~=1) & FourWave==1, cluster(PanelID)
ologit ShiftPartyID2 ShiftLegParty i.time if FourWave==1, cluster(PanelID)  // Significant at 10%


***********************************************************************************************
*** Table A.6: Robustness checks using Shift in State House or Senate, President and Voters ***
***********************************************************************************************

** Panel I
ologit ShiftPartyID ShiftHouseParty i.time, cluster(PanelID)
ologit ShiftPartyID ShiftSenParty i.time, cluster(PanelID) 
ologit ShiftPartyID ShiftPresParty i.time, cluster(PanelID)
ologit ShiftPartyID ShiftVoters i.time, cluster(PanelID)
ologit ShiftPartyID ShiftGovParty ShiftPresParty ShiftVoters i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1) & (ShiftPartyID~=-2 & ShiftPartyID~=2), cluster(PanelID)

** Panel II
ologit ShiftPartyID2 ShiftHouseParty i.time, cluster(PanelID)
ologit ShiftPartyID2 ShiftSenParty i.time, cluster(PanelID) 
ologit ShiftPartyID2 ShiftPresParty i.time, cluster(PanelID)
ologit ShiftPartyID2 ShiftVoters i.time, cluster(PanelID) 
ologit ShiftPartyID2 ShiftGovParty ShiftPresParty ShiftVoters i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1) & (ShiftPartyID~=-2 & ShiftPartyID~=2), cluster(PanelID)


*******************************************************************
*** Table A.7: Separating moves to left/right in party in power ***
*******************************************************************
gen MOVEright = 0 if ShiftGovParty~=.
gen MOVEleft = 0 if ShiftGovParty~=.
replace MOVEright = 1 if ShiftGovParty==2
replace MOVEleft = 1 if ShiftGovParty==-2

** Panel I
ologit ShiftPartyID MOVE* i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID) 
test MOVEright=-MOVEleft
ologit ShiftPartyID MOVE* i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1) & (ShiftPartyID~=-2 & ShiftPartyID~=2), cluster(PanelID)
test MOVEright=-MOVEleft
ologit ShiftPartyID MOVE*  i.time if l.PartyID~=2 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID) 
test MOVEright=-MOVEleft

** Panel II
ologit ShiftPartyID2 MOVE* i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID) 
test MOVEright=-MOVEleft
ologit ShiftPartyID2 MOVE* i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1) & (ShiftPartyID~=-2 & ShiftPartyID~=2), cluster(PanelID)
test MOVEright=-MOVEleft
ologit ShiftPartyID2 MOVE*  i.time if l.PartyID~=2 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID) 
test MOVEright=-MOVEleft


****************************************************************
***   Table A.8: Robustnes check ideological self-placement  ***
****************************************************************
gen ShiftLibCons=. 
replace ShiftLibCons= l.LibCons - LibCons  // Positive numbers = move to MORE Conservative placement

reg ShiftLibCons ShiftGovParty i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
reg ShiftLibCons ShiftGovParty i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1) & FourWave==1, cluster(PanelID)
reg ShiftLibCons MOVE* i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
reg ShiftLibCons MOVE* i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1) & FourWave==1, cluster(PanelID)


************************************************************
***  Table A.9: Robustness check using placebo outcomes  ***
************************************************************
gen ShiftHours = a_8a - l.a_8a if a_8a~=0 & l.a_8a~=0 // Pos value implies more hours of work relative to previous survey wave
gen ShiftSalary = a_9b - l.a_9b if a_9b>10000 & l.a_9b>10000 // Pos value implies real salary increase

reg ShiftHours ShiftGovParty i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
reg ShiftHours MOVE* i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
reg ShiftSalary ShiftGovParty i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
reg ShiftSalary MOVE* i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)


*********************************************************************************************
*** Table A.13: Robustness check 'hiding' partisanship by not answering party-ID question ***
*********************************************************************************************
** Define partisan aligment between state governor and ASAP respondent
gen ABS_ShiftGov = abs(ShiftGovParty)/2
gen temp = .
replace temp = 1 if l.Align==1 & ABS_ShiftGov==1 // highest, but ns from 3,4
replace temp = 2 if l.Align==1 & ABS_ShiftGov==0 // lowest & significant from others
replace temp = 3 if l.Align==0 & ABS_ShiftGov==1
replace temp = 4 if l.Align==0 & ABS_ShiftGov==0
tab HidePartyID temp, chi2 col
drop temp


**********************************************************************************
*** Table A.14: Robustness checks using state political (in)stability measures ***
**********************************************************************************
** Panel I
ologit ShiftPartyID ShiftGovParty Number_WWII i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID) 
ologit ShiftPartyID ShiftGovParty Number_WWI i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID ShiftLegParty Number_WWII i.time, cluster(PanelID)
ologit ShiftPartyID ShiftLegParty Number_WWI i.time, cluster(PanelID) 

** Panel II
ologit ShiftPartyID2 ShiftGovParty Number_WWII i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)  
ologit ShiftPartyID2 ShiftGovParty Number_WWI i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID2 ShiftLegParty Number_WWII i.time, cluster(PanelID)
ologit ShiftPartyID2 ShiftLegParty Number_WWI i.time, cluster(PanelID) 


*********************************************************************************
***  Figure A.8: Robustness check dropping states or survey waves one by one  ***
*********************************************************************************
forvalues k = 1(1)50 {
ologit ShiftPartyID ShiftGovParty i.time if state~=`k' & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
	estimates store STATE`k'
	}
	
coefplot STATE*, keep(ShiftGovParty) levels(95) legend(off) ytitle("Coefficient estimates (95% confidence intervals)") ylabel(-0.5 -0.25 0 0.25 0.5) xtitle("Excluded state") mstyle(p1) mcolor(black) ciopts(lcolor(black)) xlabel(0.52 "AL" 0.54 "AK" 0.56 "AZ" 0.58 "AR" 0.60 "CA" 0.62 "CO" 0.64 "CT" 0.666 "DE" 0.68 "FL" 0.70 "GA" 0.72 "HI" 0.74 "ID" 0.76 "IL" 0.78 "IN" 0.79 "IA" 0.80 "KS" 0.82 "KY" 0.84 "LA" 0.86 "ME" 0.88 "MD" 0.90 "MA" 0.92 "MI" 0.94 "MN" 0.96 "MS" 0.98 "MO" 1.000 "MT" 1.02 "NE" 1.04 "NV" 1.06 "NH" 1.08 "NJ" 1.10 "NM" 1.12 "NY" 1.14 "NC" 1.16 "ND" 1.18 "OH" 1.20 "OK" 1.22 "OR" 1.24 "PA" 1.26 "RI" 1.28 "SC" 1.30 "SD" 1.32 "TN" 1.34 "TX" 1.36 "UT" 1.38 "VT" 1.40 "VA" 1.42 "WA" 1.44 "WV" 1.46 "WI" 1.48 "WY",labsize(*.75) angle(vertical)) vertical yline(0)

graph save "Graph" "$paper\FigA8_State.gph", replace

drop _est*

forvalues k = 1(1)10 {
ologit ShiftPartyID ShiftGovParty i.time if time~=`k' & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
	estimates store YEAR`k'
	}
coefplot YEAR*, keep(ShiftGovParty) levels(95) legend(off) ytitle("Coefficient estimates (95% confidence intervals)") ylabel(-0.5 -0.25 0 0.25 0.5) xtitle("Excluded survey wave") mstyle(p1) mcolor(black) ciopts(lcolor(black)) xlabel(0.58 "1964" 0.672 "1968" 0.764 "1974" 0.857 "1978" 0.949 "1984" 1.041 "1988" 1.133 "1994" 1.226 "1998" 1.318 "2004" 1.41 "2008") vertical  yline(0)

graph save "Graph" "$paper\FigA8_Year.gph", replace

drop _est*


**************************************
**************************************
*****   HETEROGENEITY CHECKS    ******
**************************************
**************************************

** Appointed by governor (consent) or not
gen Appointed=.
replace Appointed=1 if Position<=3
replace Appointed=0 if Position>=4 & Position~=.

** Contact frequency with governor and staff
egen Contacts = rowmean(ContactGov_raw ContactGovStaff_raw)

** Contact frequency with state legislature and their staff
egen Contacts_Leg = rowmean(ContactLeg_raw ContactLegStaff_raw)


*****************************************
***   Table 3: Heterogeneity checks   ***
*****************************************
** Panel I
ologit ShiftPartyID ShiftGovParty i.time if Appointed==1 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID ShiftGovParty i.time if Appointed==0 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID ShiftGovParty i.time if Contacts<=3 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID ShiftGovParty i.time if Contacts>=3.5 & Contacts~=. & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID ShiftLegParty i.time if Contacts_Leg<=3, cluster(PanelID)
ologit ShiftPartyID ShiftLegParty i.time if Contacts_Leg>=3.5 & Contacts_Leg~=., cluster(PanelID) 

** Panel II
ologit ShiftPartyID2 ShiftGovParty i.time if Appointed==1 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID2 ShiftGovParty i.time if Appointed==0 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID2 ShiftGovParty i.time if Contacts<=3 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID2 ShiftGovParty i.time if Contacts>=3.5 & Contacts~=. & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID2 ShiftLegParty i.time if Contacts_Leg<=3, cluster(PanelID)
ologit ShiftPartyID2 ShiftLegParty i.time if Contacts_Leg>=3.5 & Contacts_Leg~=., cluster(PanelID) 


***** Extra check on position = 'other' category; mostly civil service/merit appointments
** (mentioned in main text)
ologit ShiftPartyID ShiftGovParty i.time if Position==7 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID2 ShiftGovParty i.time if Position==7 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)


********************************************************************
***  Table A.10: Heterogeneity results using interaction models  ***
********************************************************************
gen ContactsDUM = 1 if Contacts<=3
replace ContactsDUM = 0 if Contacts>=3.5 & Contacts~=.

***** Correlation contacts and appointment
** (mentioned in main text)
pwcorr Appointed ContactsDUM if wave==1, sig obs

***** Correlation contacts, appointment, and policy task focus
** (response to APSR reviewer; not included in main text)
egen sum = rowtotal(a_5a a_6a a_7a)
gen Policy = (a_6a/sum)*100
egen Mean_Policy= mean(Policy)
gen Pol_heavy=.
replace Pol_heavy=1 if (Policy > Mean_Policy) & Policy~=.
replace Pol_heavy=0 if (Policy <= Mean_Policy) & Policy~=.
pwcorr Appointed ContactsDUM Pol_heavy if wave==1, sig obs


** Panel I
ologit ShiftPartyID c.ShiftGovParty##c.Appointed i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
test c.ShiftGovParty + c.ShiftGovParty#c.Appointed = 0
ologit ShiftPartyID c.ShiftGovParty##c.ContactsDUM i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
test c.ShiftGovParty + c.ShiftGovParty#c.ContactsDUM = 0
ologit ShiftPartyID c.ShiftGovParty##c.Appointed c.ShiftGovParty##c.ContactsDUM i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
test c.ShiftGovParty + c.ShiftGovParty#c.Appointed = 0
test c.ShiftGovParty + c.ShiftGovParty#c.ContactsDUM = 0

** Panel II
ologit ShiftPartyID2 c.ShiftGovParty##c.Appointed i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
test c.ShiftGovParty + c.ShiftGovParty#c.Appointed = 0
ologit ShiftPartyID2 c.ShiftGovParty##c.ContactsDUM i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
test c.ShiftGovParty + c.ShiftGovParty#c.ContactsDUM = 0
ologit ShiftPartyID2 c.ShiftGovParty##c.Appointed c.ShiftGovParty##c.ContactsDUM i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
test c.ShiftGovParty + c.ShiftGovParty#c.Appointed = 0
test c.ShiftGovParty + c.ShiftGovParty#c.ContactsDUM = 0


********************************************************************
*** Table A.11: Alternative operationalization of resp. contacts ***
******************************************************************** 
** Columns 1-2: Governor only
ologit ShiftPartyID ShiftGovParty i.time if ContactGov_freq==1 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID ShiftGovParty i.time if ContactGov_freq==0 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID2 ShiftGovParty i.time if ContactGov_freq==1 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID2 ShiftGovParty i.time if ContactGov_freq==0 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)

** Columns 3-4: Governor staff only
ologit ShiftPartyID ShiftGovParty i.time if ContactGovStaff_freq==1 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID ShiftGovParty i.time if ContactGovStaff_freq==0 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID2 ShiftGovParty i.time if ContactGovStaff_freq==1 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID2 ShiftGovParty i.time if ContactGovStaff_freq==0 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)


*******************************************************************************************
*** Table A.12: Heterogeneity by Partisan Primaries and/or Voter Registration in state  ***
*******************************************************************************************
gen Identifiable_Party = 1 if state~=.
replace Identifiable_Party = 0 if state==1 | state==3 | state==4 | state==6 | state==10 | state==13 | state==14 | state==15 | state==16 | state==21 | state==22 | state==23 | state==24 | state==25 | state==26 | state==29 | state==33 | state==35 | state==39 | state==40 | state==42 | state==43 | state==45 | state==46 | state==48 | state==49 | state==50

gen Unidentifiable_Party = 0 if state~=.
replace Unidentifiable_Party = 1 if state==1 | state==10 | state==13 | state==14 | state==22 | state==23 | state==24 | state==25 | state==26 | state==35 | state==40 | state==42 | state==43 | state==45 | state==46 | state==49

** Panel I
ologit ShiftPartyID ShiftGovParty i.time if Identifiable_Party==1 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID ShiftGovParty i.time if Identifiable_Party==0 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID ShiftGovParty i.time if Unidentifiable_Party==1 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID ShiftGovParty i.time if Unidentifiable_Party==0 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)

** Panel II
ologit ShiftPartyID2 ShiftGovParty i.time if Identifiable_Party==1 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID2 ShiftGovParty i.time if Identifiable_Party==0 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID2 ShiftGovParty i.time if Unidentifiable_Party==1 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID2 ShiftGovParty i.time if Unidentifiable_Party==0 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)

** Not reported in paper -- only using very recent samples as robustness check
ologit ShiftPartyID ShiftGovParty i.time if Identifiable_Party==1 & year>=1988 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID ShiftGovParty i.time if Identifiable_Party==0 & year>=1988 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID ShiftGovParty i.time if Unidentifiable_Party==1 & year>=1988 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID ShiftGovParty i.time if Unidentifiable_Party==0 & year>=1988 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)

ologit ShiftPartyID ShiftGovParty i.time if Identifiable_Party==1 & year>=1998 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID ShiftGovParty i.time if Identifiable_Party==0 & year>=1998 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID ShiftGovParty i.time if Unidentifiable_Party==1 & year>=1998 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
ologit ShiftPartyID ShiftGovParty i.time if Unidentifiable_Party==0 & year>=1998 & (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)

** Not reported in paper -- Interaction models
ologit ShiftPartyID c.ShiftGovParty##c.Identifiable_Party i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
test c.ShiftGovParty + c.ShiftGovParty#c.Identifiable_Party = 0
ologit ShiftPartyID c.ShiftGovParty##c.Unidentifiable_Party i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
test c.ShiftGovParty + c.ShiftGovParty#c.Unidentifiable_Party = 0

ologit ShiftPartyID2 c.ShiftGovParty##c.Identifiable_Party i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
test c.ShiftGovParty + c.ShiftGovParty#c.Identifiable_Party = 0
ologit ShiftPartyID2 c.ShiftGovParty##c.Unidentifiable_Party i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
test c.ShiftGovParty + c.ShiftGovParty#c.Unidentifiable_Party = 0


************************************************************************
*** Figure A.5: Heterogeneity by time on policy tasks within agency  ***
************************************************************************

** Left panel
ologit ShiftPartyID c.Policy##c.ShiftGovParty i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
matrix b=e(b) 
matrix V=e(V)
scalar b1=b[1,1] 
scalar b2=b[1,2]
scalar b3=b[1,3]
scalar varb1=V[1,1] 
scalar varb2=V[2,2] 
scalar varb3=V[3,3]
scalar covb1b3=V[1,3] 
scalar covb2b3=V[2,3]
scalar list b1 b2 b3 varb1 varb2 varb3 covb1b3 covb2b3
gen INT=b2+b3*Policy  
gen conse=sqrt(varb2+varb3*(Policy^2)+2*covb2b3*Policy) 
gen a=1.96*conse
gen upper=INT+a
gen lower=INT-a
graph twoway (hist Policy, width(0.5) percent color(gs14) yaxis(2)) (line INT Policy, sort clwidth(medium) clcolor(blue) clcolor(black) yaxis(1)) (line upper Policy, sort clpattern(dash) clwidth(thin) clcolor(black)) (line lower Policy, sort clpattern(dash) clwidth(thin) clcolor(black)), xlabel(#10, labsize(2.5)) ylabel(-0.5(0.25)1.5, axis(1) labsize(2.5)) ylabel(0(2)20, axis(2) labsize(2.5)) legend(col(1) order(2) label(2 "95% Confidence Interval") label(3 " ")) yline(0, lcolor(black)) xtitle(Share of time on policy, size(3)) xsca(titlegap(2)) ysca(titlegap(2)) ytitle("Marginal Effect", size(3)) scheme(s2mono) graphregion(fcolor(white)) title("Dep.Var. = Shift Party ID")
drop INT conse a upper lower  


** Right panel
ologit ShiftPartyID2 c.Policy##c.ShiftGovParty i.time, cluster(PanelID)
matrix b=e(b) 
matrix V=e(V)
scalar b1=b[1,1] 
scalar b2=b[1,2]
scalar b3=b[1,3]
scalar varb1=V[1,1] 
scalar varb2=V[2,2] 
scalar varb3=V[3,3]
scalar covb1b3=V[1,3] 
scalar covb2b3=V[2,3]
scalar list b1 b2 b3 varb1 varb2 varb3 covb1b3 covb2b3
gen INT=b2+b3*Policy  
gen conse=sqrt(varb2+varb3*(Policy^2)+2*covb2b3*Policy) 
gen a=1.96*conse
gen upper=INT+a
gen lower=INT-a
graph twoway (hist Policy, width(0.5) percent color(gs14) yaxis(2)) (line INT Policy, sort clwidth(medium) clcolor(blue) clcolor(black) yaxis(1)) (line upper Policy, sort clpattern(dash) clwidth(thin) clcolor(black)) (line lower Policy, sort clpattern(dash) clwidth(thin) clcolor(black)), xlabel(#10, labsize(2.5)) ylabel(-0.5(0.25)1.5, axis(1) labsize(2.5)) ylabel(0(2)20, axis(2) labsize(2.5)) legend(col(1) order(2) label(2 "95% Confidence Interval") label(3 " ")) yline(0, lcolor(black)) xtitle(Share of time on policy, size(3)) xsca(titlegap(2)) ysca(titlegap(2)) ytitle("Marginal Effect", size(3)) scheme(s2mono) graphregion(fcolor(white)) title("Dep.Var. = Shift Party ID (det.)")
drop INT conse a upper lower 


*****************************************************************************
*** Figures A.3 and A.4: Heterogeneity by political polarization in state ***
*****************************************************************************
preserve
drop if (polar_asap<0.1 | polar_asap>=4) & polar_asap~=. // Exclude 1% outliers at both extremes (10 obs.)

** Figure A.3: ASAP-based polarization proxy
ologit ShiftPartyID c.polar_asap##c.ShiftGovParty i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
matrix b=e(b) 
matrix V=e(V)
scalar b1=b[1,1] 
scalar b2=b[1,2]
scalar b3=b[1,3]
scalar varb1=V[1,1] 
scalar varb2=V[2,2] 
scalar varb3=V[3,3]
scalar covb1b3=V[1,3] 
scalar covb2b3=V[2,3]
scalar list b1 b2 b3 varb1 varb2 varb3 covb1b3 covb2b3
gen INT=b2+b3*polar_asap  
gen conse=sqrt(varb2+varb3*(polar_asap^2)+2*covb2b3*polar_asap) 
gen a=1.96*conse
gen upper=INT+a
gen lower=INT-a
graph twoway (hist polar_asap, start(0) width(0.2) percent color(gs14) yaxis(2)) (line INT polar_asap, sort clwidth(medium) clcolor(blue) clcolor(black) yaxis(1)) (line upper polar_asap, sort clpattern(dash) clwidth(thin) clcolor(black)) (line lower polar_asap, sort clpattern(dash) clwidth(thin) clcolor(black)), xlabel(#10, labsize(2.5)) ylabel(-.5(.5)2, axis(1) labsize(2.5)) ylabel(0(3)15, axis(2) labsize(2.5)) legend(col(1) order(2) label(2 "95% Confidence Interval") label(3 " ")) yline(0, lcolor(black)) xtitle("Absolute difference between party positions on Lib-Con scale", size(3)) xsca(titlegap(2)) ysca(titlegap(2)) ytitle("Marginal Effect", size(3)) scheme(s2mono) graphregion(fcolor(white)) title("Dep.Var. = Shift Party ID", size(medium))
drop INT conse a upper lower  
graph save "Graph" "$paper\F1.gph", replace

ologit ShiftPartyID2 c.polar_asap##c.ShiftGovParty i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
matrix b=e(b) 
matrix V=e(V)
scalar b1=b[1,1] 
scalar b2=b[1,2]
scalar b3=b[1,3]
scalar varb1=V[1,1] 
scalar varb2=V[2,2] 
scalar varb3=V[3,3]
scalar covb1b3=V[1,3] 
scalar covb2b3=V[2,3]
scalar list b1 b2 b3 varb1 varb2 varb3 covb1b3 covb2b3
gen INT=b2+b3*polar_asap  
gen conse=sqrt(varb2+varb3*(polar_asap^2)+2*covb2b3*polar_asap) 
gen a=1.96*conse
gen upper=INT+a
gen lower=INT-a
graph twoway (hist polar_asap, start(0) width(0.2) percent color(gs14) yaxis(2)) (line INT polar_asap, sort clwidth(medium) clcolor(blue) clcolor(black) yaxis(1)) (line upper polar_asap, sort clpattern(dash) clwidth(thin) clcolor(black)) (line lower polar_asap, sort clpattern(dash) clwidth(thin) clcolor(black)), xlabel(#10, labsize(2.5)) ylabel(#6, axis(1) labsize(2.5)) ylabel(0(3)15, axis(2) labsize(2.5)) legend(col(1) order(2) label(2 "95% Confidence Interval") label(3 " ")) yline(0, lcolor(black)) xtitle("Absolute difference between party positions on Lib-Con scale", size(3)) xsca(titlegap(2)) ysca(titlegap(2)) ytitle("Marginal Effect", size(3)) scheme(s2mono) graphregion(fcolor(white)) title("Dep.Var. = Shift Party ID (det)", size(medium))
drop INT conse a upper lower 
graph save "Graph" "$paper\F2.gph", replace
graph combine "$paper\F1.gph" "$paper\F2.gph", row(1)
graph save "Graph" "$paper\FigA4a.gph", replace

restore

** Figure A.4: NOMINATE-based polarization proxy
preserve
drop if (polar_poole<0.3 | polar_poole>=0.96) & polar_poole~=. // Exclude 1% outliers at both extremes (48 obs.)

ologit ShiftPartyID c.polar_poole##c.ShiftGovParty i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
matrix b=e(b) 
matrix V=e(V)
scalar b1=b[1,1] 
scalar b2=b[1,2]
scalar b3=b[1,3]
scalar varb1=V[1,1] 
scalar varb2=V[2,2] 
scalar varb3=V[3,3]
scalar covb1b3=V[1,3] 
scalar covb2b3=V[2,3]
scalar list b1 b2 b3 varb1 varb2 varb3 covb1b3 covb2b3
gen INT=b2+b3*polar_poole  
gen conse=sqrt(varb2+varb3*(polar_poole^2)+2*covb2b3*polar_poole) 
gen a=1.96*conse
gen upper=INT+a
gen lower=INT-a
graph twoway (hist polar_poole, start(0.15) width(0.025) percent color(gs14) yaxis(2)) (line INT polar_poole, sort clwidth(medium) clcolor(blue) clcolor(black) yaxis(1)) (line upper polar_poole, sort clpattern(dash) clwidth(thin) clcolor(black)) (line lower polar_poole, sort clpattern(dash) clwidth(thin) clcolor(black)), xlabel(0.1(0.1)1, labsize(2.5)) ylabel(#6, axis(1) labsize(2.5)) ylabel(0(1)10, axis(2) labsize(2.5)) legend(col(1) order(2) label(2 "95% Confidence Interval") label(3 " ")) yline(0, lcolor(black)) xtitle("Absolute difference between party positions", size(3)) xsca(titlegap(2)) ysca(titlegap(2)) ytitle("Marginal Effect", size(3)) scheme(s2mono) graphregion(fcolor(white)) title("Dep.Var. = Shift Party ID", size(medium))
drop INT conse a upper lower  
graph save "Graph" "$paper\F1.gph", replace


ologit ShiftPartyID2 c.polar_poole##c.ShiftGovParty i.time if (ShiftGovParty~=-1 & ShiftGovParty~=1), cluster(PanelID)
matrix b=e(b) 
matrix V=e(V)
scalar b1=b[1,1] 
scalar b2=b[1,2]
scalar b3=b[1,3]
scalar varb1=V[1,1] 
scalar varb2=V[2,2] 
scalar varb3=V[3,3]
scalar covb1b3=V[1,3] 
scalar covb2b3=V[2,3]
scalar list b1 b2 b3 varb1 varb2 varb3 covb1b3 covb2b3
gen INT=b2+b3*polar_poole 
gen conse=sqrt(varb2+varb3*(polar_poole^2)+2*covb2b3*polar_poole) 
gen a=1.96*conse
gen upper=INT+a
gen lower=INT-a
graph twoway (hist polar_poole, start(0.15) width(0.025) percent color(gs14) yaxis(2)) (line INT polar_poole, sort clwidth(medium) clcolor(blue) clcolor(black) yaxis(1)) (line upper polar_poole, sort clpattern(dash) clwidth(thin) clcolor(black)) (line lower polar_poole, sort clpattern(dash) clwidth(thin) clcolor(black)), xlabel(0.1(0.1)1, labsize(2.5)) ylabel(#6, axis(1) labsize(2.5)) ylabel(0(1)10, axis(2) labsize(2.5)) legend(col(1) order(2) label(2 "95% Confidence Interval") label(3 " ")) yline(0, lcolor(black)) xtitle("Absolute difference between party positions", size(3)) xsca(titlegap(2)) ysca(titlegap(2)) ytitle("Marginal Effect", size(3)) scheme(s2mono) graphregion(fcolor(white)) title("Dep.Var. = Shift Party ID (det)", size(medium))
drop INT conse a upper lower  
graph save "Graph" "$paper\F2.gph", replace
graph combine "$paper\F1.gph" "$paper\F2.gph", row(1)
graph save "Graph" "$paper\FigA4b.gph", replace

restore